﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;

namespace Dycox.Linq
{
    [DataContract]
    public class QueryResult
    {
        protected internal QueryResult()
        {
        }

        public QueryResult(ICollection objects)
            : this(objects, null, 0)
        {

        }

        public QueryResult(ICollection objects, QueryArgs args, int total)
        {
            Initialize(objects, args, total);
        }

        internal void Initialize(ICollection objects, QueryArgs args, int total)
        {
            if (objects == null)
                throw new ArgumentNullException("objects");

            bool paging;

            _args = args;
            _total = total;

            if (args != null)
            {
                _pageIndex = args.PageIndex;
                paging = args.PageSize > 0;
            }
            else
                paging = false;

            if (paging)
            {
                if (total > 0)
                    _pageCount = (int)Math.Ceiling((double)total / (double)args.PageSize);

                if (_pageIndex < 0 || _pageCount == 0) _pageIndex = 0;
                else if (_pageIndex >= _pageCount) _pageIndex = _pageCount - 1;
            }
            else
            {
                _total = objects.Count;
                _pageIndex = 0;
                _pageCount = Math.Sign(_total);
            }

            Type type = objects.GetType();
            Array array;

            if (!type.IsArray)
            {
                type = type.GetInterface("ICollection`1");
                if (type != null) array = Array.CreateInstance(type.GetGenericArguments()[0], objects.Count);
                else array = new object[objects.Count];
                objects.CopyTo(array, 0);
            }
            else
                array = (Array)objects;

            _objects = array;

        }

        [DataMember(Name = "objects")]
        private Array _objects;

        public Array Objects
        {
            get { return _objects; }
        }

        [DataMember(Name = "pageCount")]
        private int _pageCount;

        public int PageCount
        {
            get { return _pageCount; }
        }

        [DataMember(Name = "pageIndex")]
        private int _pageIndex;
        
        public int PageIndex
        {
            get { return _pageIndex; }
        }

        [DataMember(Name = "total")]
        private int _total;

        public int Total
        {
            get { return _total; }
        }

        private QueryArgs _args;

        public QueryArgs Arguments
        {
            get { return _args; }
        }

    }

    //public class QueryResult<T> : QueryResult
    //{
    //    public QueryResult(ICollection<T> coll)
    //        : this(coll, null, coll.Count)
    //    {

    //    }

    //    public QueryResult(ICollection<T> coll, QueryArgs args, int total)
    //        : base(coll.ToArray(), args, total)
    //    {

    //    }

    //    public new T[] Objects
    //    {
    //        get { return (T[])base.Objects; }
    //    }
    //}
}
